package ordersrvlogic

import (
	"context"
	"errors"
	"math"
	"strings"

	"gozero-microservices/order-service/rpc/define"
	"gozero-microservices/order-service/rpc/internal/model"
	"gozero-microservices/order-service/rpc/internal/svc"
	"gozero-microservices/order-service/rpc/internal/tools"
	"gozero-microservices/order-service/rpc/types"
	"gozero-microservices/order-service/rpc/types/order"
	"gozero-microservices/order-service/rpc/utils"

	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"google.golang.org/protobuf/types/known/anypb"
)

type OrderLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

// 预定义唯一索引重复错误变量
var ErrDuplicate = errors.New("index duplicate")

/**
 * 创建订单逻辑实例
 *
 * @param context.Context ctx ----------------------必传
 * @param *svc.ServiceContext svcCtx ---------------必传
 * @return *OrderLogic
 * @author huwl
 * @date 2025/10/14 12:54:03
 */
func NewOrderLogicInstance(ctx context.Context, svcCtx *svc.ServiceContext) *OrderLogic {
	return &OrderLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

/**
 * 创建订单
 *
 * @param uint32 Platform ---------------------必传,商城平台
 * @param uint64 Uid --------------------------必传,用户ID
 * @param string Username ---------------------必传,用户名
 * @param uint32 OrderMoney -------------------非必传,订单金额
 * @param uint32 ReduceMoney ------------------非必传,减免金额
 * @param uint32 PayMoney ---------------------非必传,支付金额
 * @param uint32 OtherMoney -------------------非必传,其他金额
 * @param []*Goods Goods  ---------------------必传,商品信息
 * @param string Note -------------------------非必传,备注
 * @param *DeliveryAddress DeliveryAddress ----必传,收货地址
 * @return *order.Result, error
 * @author huwl
 * @date 2025/10/25 17:30:12
 */
func (l *OrderLogic) CreateOrder(in *order.CreateOrderRequest) (*order.Result, error) {
	if !utils.IsContainNumber[uint8]([]uint8{1, 2, 3, 4}, uint8(in.Platform)) {
		// 如果使用DTM分布式事务此处的code: codes.Aborted 表示失败
		// 如果不使用DTM分布式事务此处的code: codes.InvalidArgument
		return nil, status.Errorf(codes.Aborted, "商城平台错误")
	}
	if in.Uid <= 0 {
		return nil, status.Errorf(codes.Aborted, "用户ID不能为空")
	}
	if in.Username == "" {
		return nil, status.Errorf(codes.Aborted, "用户名不能为空")
	}
	if len(in.Goods) <= 0 {
		return nil, status.Errorf(codes.Aborted, "商品不能为空")
	}
	amount := 0
	for _, item := range in.Goods {
		if item.GoodsId <= 0 {
			return nil, status.Errorf(codes.Aborted, "商品ID不能为空")
		}
		if item.GoodsSkuId <= 0 {
			return nil, status.Errorf(codes.Aborted, "商品skuID不能为空")
		}
		if item.GoodsName == "" {
			return nil, status.Errorf(codes.Aborted, "商品名称不能为空")
		}
		if item.GoodsName == "" {
			return nil, status.Errorf(codes.Aborted, "商品名称不能为空")
		}
		if item.GoodsNum <= 0 {
			return nil, status.Errorf(codes.Aborted, "商品数量不能为空")
		}
		if item.GoodsSkuText == "" {
			return nil, status.Errorf(codes.Aborted, "商品sku规格选项不能为空")
		}

		amount += int(item.GoodsNum)
	}
	if in.DeliveryAddress.Name == "" {
		return nil, status.Errorf(codes.Aborted, "收货人姓名不能为空")
	}
	if !utils.CheckMobile(in.DeliveryAddress.Mobile) {
		return nil, status.Errorf(codes.Aborted, "请输入格式正确的手机号")
	}
	if in.DeliveryAddress.ProvinceId <= 0 {
		return nil, status.Errorf(codes.Aborted, "省份ID不能为空")
	}
	if in.DeliveryAddress.CityId <= 0 {
		return nil, status.Errorf(codes.Aborted, "城市ID不能为空")
	}
	if in.DeliveryAddress.DistrictId <= 0 {
		return nil, status.Errorf(codes.Aborted, "区县ID不能为空")
	}
	if in.DeliveryAddress.Region == "" {
		return nil, status.Errorf(codes.Aborted, "地区不能为空")
	}
	if in.DeliveryAddress.Address == "" {
		return nil, status.Errorf(codes.Aborted, "详细地址不能为空")
	}
	// 屏蔽子事务参数
	if in.Barrier.TransType == "" {
		return nil, status.Errorf(codes.Aborted, "事务类型错误")
	}
	if in.Barrier.Gid == "" {
		return nil, status.Errorf(codes.Aborted, "全局事务Id不能为空")
	}
	if in.Barrier.BranchId == "" {
		return nil, status.Errorf(codes.Aborted, "子事务Id不能为空")
	}
	if in.Barrier.BarrierId == "" {
		in.Barrier.BarrierId = "create-order"
	}

	var oid int64

	// 事务中新增订单 + 明细
	err := l.svcCtx.OrderModel.Conn().TransactCtx(context.Background(), func(ctx context.Context, s sqlx.Session) error {
		var err error

		// 新增子事务屏蔽数据
		_, err = l.svcCtx.BarrierModel.InsertTx(ctx, s, model.MallBarrier{
			TransType: in.Barrier.TransType,
			Gid:       in.Barrier.Gid,
			BranchId:  in.Barrier.BranchId,
			BarrierId: in.Barrier.BarrierId,
			Reason:    in.Barrier.Reason,
		})
		if err != nil {
			// 校验是否唯一索引冲突错误
			b := l.svcCtx.BarrierModel.IsDuplicateEntryError(err)
			if b {
				return ErrDuplicate
			}

			return err // 返回错误，事务会自动回滚
		}

		// 新增订单
		oid, err = l.svcCtx.OrderModel.InsertTx(ctx, s, model.MallOrder{
			Platform:    uint8(in.Platform),
			Uid:         in.Uid,
			Username:    in.Username,
			Amount:      uint8(amount),
			OrderMoney:  in.OrderMoney,
			ReduceMoney: in.ReduceMoney,
			PayMoney:    in.PayMoney,
			OtherMoney:  in.OrderMoney,
			Note:        in.Note,
			CreateTime:  types.Now(),
		})
		if err != nil {
			return err // 返回错误，事务会自动回滚
		}

		// 新增订单收货地址

		// 新增订单明细
		orderItems := []interface{}{}
		for _, value := range in.Goods {
			orderItems = append(orderItems, model.MallOrderItem{
				Oid:           uint64(oid),
				GoodsId:       value.GoodsId,
				GoodsSkuId:    value.GoodsSkuId,
				GoodsName:     value.GoodsName,
				GoodsCoverUrl: value.GoodsCoverUrl,
				GoodsNum:      uint8(value.GoodsNum),
				GoodsPrice:    value.GoodsPrice,
				GoodsSkuText:  value.GoodsSkuText,
				PayMoney:      value.PayMoney,
				OtherMoney:    value.OtherMoney,
				Note:          value.Note,
				Status:        int8(value.Status),
			})
		}
		err = l.svcCtx.OrderItemModel.BatchInsertTx(ctx, s, orderItems)
		if err != nil {
			return err // 返回错误，事务会自动回滚
		}

		return nil
	})
	if err != nil {
		if err == ErrDuplicate {
			return &order.Result{
				Code: 200,
				Msg:  "已创建订单成功，无需重试",
			}, nil
		}

		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 组装返回数据
	anyData, toRrr := utils.Int64ToAny(oid)
	if toRrr != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	data := make(map[string]*anypb.Any)
	data["oid"] = anyData

	return &order.Result{
		Code: 200,
		Msg:  "创建订单成功",
		Data: data,
	}, nil
}

/**
 * 删除
 *
 * @param uint64 Oid --------------------------必传,订单编号
 * @return *order.Result, error
 * @author huwl
 * @date 2025/10/26 17:30:12
 */
func (l *OrderLogic) DeleteOrder(in *order.DeleteRequest) (*order.Result, error) {
	if in.Ids == "" {
		return nil, status.Errorf(codes.Aborted, "订单编号错误")
	}

	// 操作数据库
	err := l.svcCtx.OrderModel.EditByParams(l.ctx, map[string]interface{}{
		"is_delete": 1,
	}, map[string]interface{}{
		"oid IN (?)": utils.IntSplit(in.Ids, ","),
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &order.Result{
		Code: 200,
		Msg:  "删除订单成功",
	}, nil
}

/**
 * 销毁
 *
 * @param uint64 Oid --------------------------必传,订单编号
 * @return *order.Result, error
 * @author huwl
 * @date 2025/10/26 17:30:12
 */
func (l *OrderLogic) DestroyOrder(in *order.CreateOrderRequest) (*order.Result, error) {
	if in.Barrier.Gid == "" {
		return nil, status.Errorf(codes.Aborted, "事务编号错误")
	}

	// 通过事务编号获取订单编号
	ri, err := tools.NewRedisInstance(l.svcCtx)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	oid, err := ri.RedisGet("oid:" + in.Barrier.Gid)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 操作数据库
	err = l.svcCtx.OrderModel.EditByPrimaryKey(l.ctx, map[string]interface{}{
		"is_invalid": 1,
	}, oid, "oid")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &order.Result{
		Code: 200,
		Msg:  "销毁订单成功",
	}, nil
}

/**
 * 取消
 *
 * @param uint64 Oid --------------------------必传,订单编号
 * @param string CancelReason -----------------非必传,取消原因
 * @return *order.Result, error
 * @author huwl
 * @date 2025/10/26 17:30:12
 */
func (l *OrderLogic) CancelOrder(in *order.CancelOrderRequest) (*order.Result, error) {
	if in.Oid <= 0 {
		// 如果使用DTM分布式事务此处的code: codes.Aborted 表示失败
		// 如果不使用DTM分布式事务此处的code: codes.InvalidArgument
		return nil, status.Errorf(codes.Aborted, "订单编号错误")
	}

	// 开始事务更新订单、订单明细
	err := l.svcCtx.OrderModel.Conn().TransactCtx(context.Background(), func(ctx context.Context, s sqlx.Session) error {
		// 更新订单
		err := l.svcCtx.OrderModel.EditByPrimaryKeyWithTx(ctx, s, map[string]interface{}{
			"status":        -1,
			"cancel_reason": in.CancelReason,
		}, in.Oid, "oid")
		if err != nil {
			return err
		}

		// 更新订单明细
		err = l.svcCtx.OrderItemModel.EditByParamsWithTx(ctx, s, map[string]interface{}{
			"status": -1,
		}, map[string]interface{}{
			"oid": in.Oid,
		})
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, err
	}

	return &order.Result{Code: 200, Msg: "取消订单成功"}, nil
}

/**
 * 列表
 *
 * @param uint64 Oid --------------------------非必传,订单Id
 * @param string Oids -------------------------非必传,订单Id支持多个
 * @param uint32 Platform ---------------------非必传,商城平台
 * @param uint64 Uid --------------------------非必传,用户Id
 * @param string Uids -------------------------非必传,用户Id支持多个
 * @param string Username ---------------------非必传,用户名
 * @param string GoodsName --------------------非必传,商品名称
 * @param uint32 PayChannel -------------------非必传,支付渠道
 * @param string IsDelete ---------------------非必传,是否删除
 * @param string Status -----------------------非必传,状态支持多个：1,-1
 * @param string StartCreateTime --------------非必传,开始创建时间
 * @param string EndCreateTime ----------------非必传,结束创建时间
 * @param string SortField --------------------非必传,排序字段
 * @param string SortType ---------------------非必传,排序方式
 * @param uint32 Page -------------------------非必传,页码
 * @param int32 PageSize ----------------------非必传,条数
 * @return *order.OrderListResult, error
 * @author huwl
 */
func (l *OrderLogic) OrderList(in *order.QueryOrderRequest) (*order.OrderListResult, error) {
	params := map[string]interface{}{
		"o.is_invalid": 0,
	}

	page := in.Page
	pageSize := in.PageSize
	sortType := in.SortType
	sortField := in.SortField

	// 根据商品名称搜索订单
	if in.GoodsName != "" {
		params["oi.goods_name"] = in.GoodsName
	}
	if in.Oid > 0 {
		params["o.oid"] = in.Oid
	}
	if in.Oids != "" {
		params["o.oid IN (?)"] = utils.IntSplit(strings.TrimRight(in.Oids, ","), ",")
	}
	if in.Platform > 0 {
		params["o.platform"] = in.Platform
	}
	if in.Uid > 0 {
		params["o.uid"] = in.Uid
	}
	if in.Uids != "" {
		params["o.uid IN (?)"] = utils.IntSplit(strings.TrimRight(in.Uids, ","), ",")
	}
	if in.Username != "" {
		params["o.username"] = in.Username
	}
	if in.PayChannel > 0 {
		params["o.pay_channel"] = in.PayChannel
	}
	if in.Status != "all" {
		params["o.status IN (?)"] = utils.IntSplit(strings.TrimRight(in.Status, ","), ",")
	}
	if in.IsDelete != "all" {
		params["o.is_delete"] = in.IsDelete
	}
	if in.StartCreateTime != "" {
		params["o.create_time >= ?"] = in.StartCreateTime + " 00:00:00"
	}
	if in.EndCreateTime != "" {
		params["o.create_time <= ?"] = in.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "o.oid"
	}
	if sortType == "" {
		sortType = "desc"
	}

	// 获取订单数量
	total, err := l.svcCtx.OrderModel.GetListByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	orders := []*order.Order{}
	if total > 0 {
		// 获取订单数据
		orderData := []*model.MallOrder{}
		err := l.svcCtx.OrderModel.GetListByParams(l.ctx, &orderData, params, page, int8(pageSize), sortField+" "+sortType)
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}

		// 组装订单数据
		oids := []int{}
		for _, orderValue := range orderData {
			oids = append(oids, int(orderValue.Oid))

			payChannelText := ""
			payChannel, ok := define.GetPayChannel(int(orderValue.PayChannel))["value_txt"]
			if ok {
				payChannelText = payChannel.(string)
			}

			orders = append(orders, &order.Order{
				Oid:                   orderValue.Oid,
				Platform:              uint32(orderValue.Platform),
				PlatformText:          define.GetPlatform(int(orderValue.Platform))["value_txt"].(string),
				Uid:                   orderValue.Uid,
				Username:              orderValue.Username,
				Amount:                uint32(orderValue.Amount),
				OrderMoney:            orderValue.OrderMoney,
				ReduceMoney:           orderValue.ReduceMoney,
				PayMoney:              orderValue.PayMoney,
				OtherMoney:            orderValue.OtherMoney,
				PayChannel:            uint32(orderValue.PayChannel),
				PayChannelText:        payChannelText,
				PayChannelNote:        orderValue.PayChannelNote,
				PayTime:               orderValue.PayTime.String(),
				CancelReason:          orderValue.CancelReason,
				UnsubscribeServiceFee: orderValue.UnsubscribeServiceFee,
				Note:                  orderValue.Note,
				Status:                int32(orderValue.Status),
				StatusText:            define.GetOrderStatus(int(orderValue.Status))["value_txt"].(string),
				IsDelete:              int32(orderValue.IsDelete),
				CreateTime:            orderValue.CreateTime.String(),
				UpdateTime:            orderValue.UpdateTime.String(),
			})
		}

		// 获取订单明细数据
		orderItems := []*model.MallOrderItem{}
		err = l.svcCtx.OrderItemModel.GetResultsByParams(l.ctx, &orderItems, map[string]interface{}{
			"oid IN (?)": oids,
		}, 1, -1, "id desc")
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}

		// 组装订单明细数据
		for _, v := range orders {
			for _, orderItem := range orderItems {
				if v.Oid == orderItem.Oid {
					v.OrderItems = append(v.OrderItems, &order.OrderItem{
						Id:                    orderItem.Id,
						Oid:                   orderItem.Oid,
						GoodsId:               orderItem.GoodsId,
						GoodsSkuId:            orderItem.GoodsSkuId,
						GoodsName:             orderItem.GoodsName,
						GoodsCoverUrl:         orderItem.GoodsCoverUrl,
						GoodsNum:              uint32(orderItem.GoodsNum),
						GoodsPrice:            orderItem.GoodsPrice,
						GoodsSkuText:          orderItem.GoodsSkuText,
						PayMoney:              orderItem.PayMoney,
						OtherMoney:            orderItem.OtherMoney,
						UnsubscribeServiceFee: orderItem.UnsubscribeServiceFee,
						Note:                  orderItem.Note,
						Status:                int32(orderItem.Status),
						UpdateTime:            orderItem.UpdateTime.String(),
					})
				}
			}
		}
	}

	// 计算总页数
	pageTotal := math.Ceil(float64(total) / float64(pageSize))

	return &order.OrderListResult{
		Page:      page,
		PageSize:  pageSize,
		Total:     int32(total),
		PageTotal: int32(pageTotal),
		Orders:    orders,
	}, nil
}

/**
 * 数量
 *
 * @param uint64 Oid --------------------------非必传,订单Id
 * @param string Oids -------------------------非必传,订单Id支持多个
 * @param uint32 Platform ---------------------非必传,商城平台
 * @param uint64 Uid --------------------------非必传,用户Id
 * @param string Uids -------------------------非必传,用户Id支持多个
 * @param string Username ---------------------非必传,用户名
 * @param string GoodsName --------------------非必传,商品名称
 * @param uint32 PayChannel -------------------非必传,支付渠道
 * @param string IsDelete ---------------------非必传,是否删除
 * @param string Status -----------------------非必传,状态支持多个：1,-1
 * @param string StartCreateTime --------------非必传,开始创建时间
 * @param string EndCreateTime ----------------非必传,结束创建时间
 * @return *order.TotalResult, error
 * @author huwl
 */
func (l *OrderLogic) OrderTotal(in *order.QueryOrderRequest) (*order.TotalResult, error) {
	params := map[string]interface{}{
		"o.is_invalid": 0,
	}

	page := in.Page
	pageSize := in.PageSize
	sortType := in.SortType
	sortField := in.SortField

	// 根据商品名称搜索订单
	if in.GoodsName != "" {
		params["oi.goods_name"] = in.GoodsName
	}
	if in.Oid > 0 {
		params["o.oid"] = in.Oid
	}
	if in.Oids != "" {
		params["o.oid IN (?)"] = utils.IntSplit(strings.TrimRight(in.Oids, ","), ",")
	}
	if in.Platform > 0 {
		params["o.platform"] = in.Platform
	}
	if in.Uid > 0 {
		params["o.uid"] = in.Uid
	}
	if in.Uids != "" {
		params["o.uid IN (?)"] = utils.IntSplit(strings.TrimRight(in.Uids, ","), ",")
	}
	if in.Username != "" {
		params["o.username"] = in.Username
	}
	if in.PayChannel > 0 {
		params["o.pay_channel"] = in.PayChannel
	}
	if in.Status != "all" {
		params["o.status IN (?)"] = utils.IntSplit(strings.TrimRight(in.Status, ","), ",")
	}
	if in.IsDelete != "all" {
		params["o.is_delete"] = in.IsDelete
	}
	if in.StartCreateTime != "" {
		params["o.create_time >= ?"] = in.StartCreateTime + " 00:00:00"
	}
	if in.EndCreateTime != "" {
		params["o.create_time <= ?"] = in.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "o.oid"
	}
	if sortType == "" {
		sortType = "desc"
	}

	// 获取订单数量
	total, err := l.svcCtx.OrderModel.GetListByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &order.TotalResult{Total: uint32(total)}, nil
}

/**
 * 订单详情
 *
 * @param int64 Id ----------------------------必传,订单编号
 * @return Order error
 * @author huwl
 */
func (l *OrderLogic) OrderDetail(in *order.DetailRequest) (*order.Order, error) {
	if in.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "订单编号错误")
	}

	// 获取订单数据
	orderData, err := l.svcCtx.OrderModel.FindOne(l.ctx, int64(in.Id))
	if err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return nil, status.Errorf(codes.Aborted, "订单信息错误")
		}

		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	// 获取订单明细数据
	orderItems := []*model.MallOrderItem{}
	err = l.svcCtx.OrderItemModel.GetResultsByParams(l.ctx, &orderItems, map[string]interface{}{
		"oid": orderData.Oid,
	}, 1, -1, "id desc")
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	// 组装订单明细数据
	orderItemValues := []*order.OrderItem{}
	for _, orderItemVal := range orderItems {
		orderItemValues = append(orderItemValues, &order.OrderItem{
			Id:                    orderItemVal.Id,
			Oid:                   orderItemVal.Oid,
			GoodsId:               orderItemVal.GoodsId,
			GoodsSkuId:            orderItemVal.GoodsSkuId,
			GoodsName:             orderItemVal.GoodsName,
			GoodsCoverUrl:         orderItemVal.GoodsCoverUrl,
			GoodsNum:              uint32(orderItemVal.GoodsNum),
			GoodsPrice:            orderItemVal.GoodsPrice,
			GoodsSkuText:          orderItemVal.GoodsSkuText,
			PayMoney:              orderItemVal.PayMoney,
			OtherMoney:            orderItemVal.OtherMoney,
			UnsubscribeServiceFee: orderItemVal.UnsubscribeServiceFee,
			Note:                  orderItemVal.Note,
			Status:                int32(orderItemVal.Status),
			UpdateTime:            orderItemVal.UpdateTime.String(),
		})
	}

	// 获取收货地址数据
	var orderDeliveryAddrData model.MallOrderDeliveryAddress
	err = l.svcCtx.OrderDeliveryAddressModel.Row(l.ctx, &orderDeliveryAddrData, map[string]interface{}{
		"oid": orderData.Oid,
	})
	if err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return nil, status.Errorf(codes.Aborted, "收货地址信息错误")
		}
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	payChannelText := ""
	payChannel, ok := define.GetPayChannel(int(orderData.PayChannel))["value_txt"]
	if ok {
		payChannelText = payChannel.(string)
	}

	return &order.Order{
		Oid:                   orderData.Oid,
		Platform:              uint32(orderData.Platform),
		PlatformText:          define.GetPlatform(int(orderData.Platform))["value_txt"].(string),
		Uid:                   orderData.Uid,
		Username:              orderData.Username,
		Amount:                uint32(orderData.Amount),
		OrderMoney:            orderData.OrderMoney,
		ReduceMoney:           orderData.ReduceMoney,
		PayMoney:              orderData.PayMoney,
		OtherMoney:            orderData.OtherMoney,
		PayChannel:            uint32(orderData.PayChannel),
		PayChannelText:        payChannelText,
		PayChannelNote:        orderData.PayChannelNote,
		PayTime:               orderData.PayTime.String(),
		CancelReason:          orderData.CancelReason,
		UnsubscribeServiceFee: uint32(orderData.UnsubscribeServiceFee),
		Note:                  orderData.Note,
		Status:                int32(orderData.Status),
		StatusText:            define.GetOrderStatus(int(orderData.Status))["value_txt"].(string),
		IsDelete:              int32(orderData.IsDelete),
		CreateTime:            orderData.CreateTime.String(),
		UpdateTime:            orderData.UpdateTime.String(),
		OrderItems:            orderItemValues,
		DeliveryAddress: &order.DeliveryAddress{
			Id:         orderDeliveryAddrData.Id,
			Oid:        orderDeliveryAddrData.Oid,
			Name:       orderDeliveryAddrData.Name,
			Mobile:     orderDeliveryAddrData.Mobile,
			ProvinceId: uint32(orderDeliveryAddrData.ProvinceId),
			CityId:     uint32(orderDeliveryAddrData.CityId),
			DistrictId: uint32(orderDeliveryAddrData.DistrictId),
			Region:     orderDeliveryAddrData.Region,
			Address:    orderDeliveryAddrData.Address,
			CreateTime: orderDeliveryAddrData.CreateTime.String(),
			UpdateTime: orderDeliveryAddrData.UpdateTime.String(),
		},
	}, nil
}

/**
 * 退款【退款需要还原库存操作，使用DTM分布式事务】
 *
 * @param int64 Oid ---------------------------必传,订单编号
 * @return Order error
 * @author huwl
 */
func (l *OrderLogic) RefundOrder(in *order.RefundOrderRequest) (*order.Result, error) {
	if in.Oid <= 0 {
		// 如果使用DTM分布式事务此处的code: codes.Aborted 表示失败
		// 如果不使用DTM分布式事务此处的code: codes.InvalidArgument
		return nil, status.Errorf(codes.Aborted, "订单编号错误")
	}

	// 开启事务操作
	err := l.svcCtx.OrderModel.Conn().TransactCtx(l.ctx, func(ctx context.Context, s sqlx.Session) error {
		// 更新订单
		err := l.svcCtx.OrderModel.EditByPrimaryKeyWithTx(l.ctx, s, map[string]interface{}{
			"status": define.OrderRefundStatus,
		}, in.Oid, "oid")
		if err != nil {
			return err
		}

		// 更新订单明细
		err = l.svcCtx.OrderItemModel.EditByParamsWithTx(l.ctx, s, map[string]interface{}{
			"status": define.OrderRefundStatus,
		}, map[string]interface{}{
			"oid": in.Oid,
		})
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &order.Result{Code: 200, Msg: "退款成功"}, nil
}

/**
 * 支付
 *
 * @param int64 Oid ---------------------------必传,订单编号
 * @param uint32 PayChannel -------------------必传,支付通道
 * @param string PayChannelNote ---------------非必传,支付通道备注
 * @return Order error
 * @author huwl
 */
func (l *OrderLogic) PaymentOrder(in *order.PaymentOrderRequest) (*order.Result, error) {
	if in.Oid <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "订单编号错误")
	}
	if in.PayChannel <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "支付通道错误")
	}

	// 开启事务操作
	err := l.svcCtx.OrderModel.Conn().TransactCtx(l.ctx, func(ctx context.Context, s sqlx.Session) error {
		// 更新订单
		err := l.svcCtx.OrderModel.EditByPrimaryKeyWithTx(l.ctx, s, map[string]interface{}{
			"status":           define.OrderPaymentStatus,
			"pay_time":         utils.GetDate(),
			"pay_channel":      in.PayChannel,
			"pay_channel_note": in.PayChannelNote,
		}, in.Oid, "oid")
		if err != nil {
			return err
		}

		// 更新订单明细
		err = l.svcCtx.OrderItemModel.EditByParamsWithTx(l.ctx, s, map[string]interface{}{
			"status": define.OrderPaymentStatus,
		}, map[string]interface{}{
			"oid": in.Oid,
		})
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &order.Result{Code: 200, Msg: "支付成功"}, nil
}

/**
 * 确认
 *
 * @param int64 Oid ---------------------------必传,订单编号
 * @return Order error
 * @author huwl
 */
func (l *OrderLogic) ConfirmOrder(in *order.ConfirmOrderRequest) (*order.Result, error) {
	if in.Oid <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "订单编号错误")
	}

	// 开启事务操作
	err := l.svcCtx.OrderModel.Conn().TransactCtx(l.ctx, func(ctx context.Context, s sqlx.Session) error {
		// 更新订单
		err := l.svcCtx.OrderModel.EditByPrimaryKeyWithTx(l.ctx, s, map[string]interface{}{
			"status": define.OrderEvaluateStatus,
		}, in.Oid, "oid")
		if err != nil {
			return err
		}

		// 更新订单明细
		err = l.svcCtx.OrderItemModel.EditByParamsWithTx(l.ctx, s, map[string]interface{}{
			"status": define.OrderEvaluateStatus,
		}, map[string]interface{}{
			"oid": in.Oid,
		})
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &order.Result{Code: 200, Msg: "确认成功"}, nil
}
